﻿using Cinchoo.Core;
using Cinchoo.Core.Configuration;
using Cinchoo.Core.Xml.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;

namespace ChoWorkflowDashboard
{
    [ChoNameValueConfigurationSection("wdGridStyle", BindingMode = ChoConfigurationBindingMode.OneWay)]
    public class ChoWDGridStyleObject : ChoConfigurableObject
    {
        private const string DEFAULT_GRID_COLUMN_STYLES = @"
            JOB_NAME, Job Name, 0, 100, True;
            WORKFLOW_NAME, Workflow Name, -1, 100, True;
            BATCH_ID, Batch Id, -1, 100, True;
            TASK_STATUS_DESC, Status, -1, 75, True;
            BATCH_CMD_PARAMETERS, Parameters, -1, 350, True;
            LOG_MSG, Message, -1, 250, True;
            START_TIME, Start Time, -1, 100, True;
            END_TIME, End Time, -1, 100, True;
            DURATION, Duration, -1, 110, True;
            RETRY_COUNT, Retry, -1, 50, True;
            BATCH_MACHINE_NAME, Machine, -1, 150, True;
            MODIFIED_BY, User, -1, 100, True;
            MODIFIED_DATE, Modified Date, -1, 100, True;
            EXIT_CODE, Exit, -1, 50, True;
            NEXT_RUN_TIME, Next Run, -1, 100, True;";

        [ChoPropertyInfo("gridColumnStyles")]
        public ChoCDATA GridColumnStyles;

        internal bool _firstTime = true;
        internal readonly object _padLock = new object();
        internal readonly Dictionary<string, Tuple<string, int, int, bool>> _styleDict = new Dictionary<string, Tuple<string, int, int, bool>>();

        protected override void OnAfterConfigurationObjectLoaded()
        {
            if (GridColumnStyles == null || GridColumnStyles.Value.IsNullOrWhiteSpace())
                GridColumnStyles = new ChoCDATA(DEFAULT_GRID_COLUMN_STYLES);

            LoadStyleDict();

            if (!_firstTime)
            {
                Application.Current.Dispatcher.Invoke(new Action(() =>
                {
                    if (Application.Current.MainWindow != null)
                        ((ChoMainWindow)Application.Current.MainWindow).Refresh();
                }));
            }

            _firstTime = false;

            base.OnAfterConfigurationObjectLoaded();
        }

        public string GetColumnHeader(string columnName)
        {
            return _styleDict.ContainsKey(columnName) ? _styleDict[columnName].Item1 : columnName;
        }

        public int GetColumnDisplayIndex(string columnName, int defaultValue = -1)
        {
            return _styleDict.ContainsKey(columnName) ? _styleDict[columnName].Item2 : defaultValue;
        }

        public int GetColumnWidth(string columnName, int defaultValue = 75)
        {
            return _styleDict.ContainsKey(columnName) ? _styleDict[columnName].Item3 : defaultValue;
        }

        public bool GetColumnVisibility(string columnName, bool defaultValue = false)
        {
            return _styleDict.ContainsKey(columnName) ? _styleDict[columnName].Item4 : defaultValue;
        }

        private void LoadStyleDict()
        {
            lock (_padLock)
            {
                _styleDict.Clear();

                string gridColumnStyles = GridColumnStyles == null ? null : GridColumnStyles.Value.NTrim();
                if (gridColumnStyles.IsNullOrWhiteSpace())
                    gridColumnStyles = DEFAULT_GRID_COLUMN_STYLES;

                string[] tokens = null;
                foreach (string gridColumnStyle in gridColumnStyles.SplitNTrim(';'))
                {
                    if (gridColumnStyle.IsNullOrWhiteSpace()) continue;
                    tokens = gridColumnStyle.SplitNTrim(',');

                    if (tokens.Length == 5)
                    {
                        try
                        {
                            if (!_styleDict.ContainsKey(tokens[0].ToUpper()))
                                _styleDict.Add(tokens[0].ToUpper(), new Tuple<string, int, int, bool>(tokens[1], 
                                    Convert.ToInt32(tokens[2]), Convert.ToInt32(tokens[3]),
                                    Convert.ToBoolean(tokens[4])
                                    ));
                        }
                        catch { }
                    }
                }
            }
        }
    }
}
